package components.editor
{
	import UIFree.ObjectEvent;
	import UIFree.uif_bitmap;
	import UIFree.uif_component;
	import UIFree.uif_ecomponent;
	
	import UIUtils.uif_util;
	
	import classes.Commands.c_holeSelectCommand;
	import classes.Commands.c_linkCommand;
	import classes.c_events;
	import classes.c_locale;
	import classes.c_uiEvents;
	
	import components.c_component;
	import components.c_pcomponent;
	import components.scanario.elements.c_eventElement;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.Shape;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BlurFilter;
	import flash.filters.GlowFilter;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	public class c_holeyElement extends c_bitmapElement {
		private var _curHole		: int;
		private var _holes			: Array;
		private var _holeFocus		: int;
		private var _focusLayer		: Bitmap;
		private var _gfilter		: GlowFilter;
		private var _bfilter		: BlurFilter;
		private var _flFrame		: Number;			
		
		public function c_holeyElement(parent:uif_component, rect:Rectangle, source:DisplayObject, a_holes: Array) {
			super(parent, rect, source);
			_focusLayer = new Bitmap();
			addChild(_focusLayer);
			
			_gfilter = new GlowFilter(0xFFFFFF, 1, 4, 4, 4, 2, false, true); 
//			_bfilter = new BlurFilter(1, 1);
			
			_holeFocus = -1;
			createHoles(a_holes);
			_flFrame = 0;
		}
		
		override protected function nameClass(): String {
			return locale.HOLES;
		}
		
		override protected function listenEvents():void {
			super.listenEvents();
			addEvent(MouseEvent.MOUSE_MOVE, doMouseMove, stage);
			addEvent(Event.ENTER_FRAME, doFrame);
			addEvent(MouseEvent.MOUSE_DOWN, doRectDown, editor.dragRect);
		}
		
		protected function doFrame(e: Event): void {
			function sin(ix: Number): Number {
				return (Math.sin(ix) + 1) / 2;
			}
			_flFrame += 0.2;
			_focusLayer.transform.colorTransform = new ColorTransform(sin(_flFrame), sin(_flFrame + Math.PI / 2), sin(_flFrame + Math.PI));
		}
		
		override protected function getActions():Array {
			return [
				{
					caption	: locale.INSERTPHOTO,
					event	: c_uiEvents.OPENFILE
				}
			]
		}
		
		override public function hitTest(stageX: Number, stageY: Number): Boolean {
			return ((_holeFocus > -1) && !holeFocusImage)?true:super.hitTest(stageX, stageY); 
		}
		
		protected function doMouseMove(e: MouseEvent): void {
			if (stage) {
				var _index: int = -1;
				var p: Point = new Point(stage.mouseX, stage.mouseY);
				if (hitTestPoint(p.x, p.y)) {
					for (var i: int=0; i<_holes.length; i++) 
						if (_holes[i].mask.hitTestPoint(p.x, p.y)) {
							var lp: Point = _holes[i].mask.globalToLocal(p); 
							if (_holes[i].mask.bitmapData.getPixel32(lp.x, lp.y) > 0) {
								_index = i;
								break;
							}
						}
				}
				if (_holeFocus != _index) doHoleFocus(_index);
			}
		}
		
		protected function doHoleFocus(a_index: int): void {
			if (_holeFocus > -1) doHoleUnFocus();
			_holeFocus = a_index;
			if (_holeFocus > -1) updateHoleFocus();
		}
		
		public function get holeFocus(): int {
			return _holeFocus;
		}
		
		public function get holeFocusImage(): c_baseElement {
			if (holeFocus > -1) return _holes[holeFocus].image;
			else return null;
		}
		
		public function getHole(index: int): Object {
			return _holes[index];
		}
		
		protected function updateHoleFocus(asFocus: Boolean=true): void {
			if (_focusLayer.bitmapData) _focusLayer.bitmapData.dispose();
			if ((_holeFocus > -1) && asFocus) {
				var space: Number = 5;
				var fb: Bitmap = _holes[_holeFocus].mask;
				var p: Point = globalToLocal(fb.parent.localToGlobal(new Point(fb.x, fb.y)));
				_focusLayer.bitmapData = new BitmapData(fb.bitmapData.width + space * 2, fb.bitmapData.height + space * 2, true, 0);
				_focusLayer.bitmapData.applyFilter(fb.bitmapData, fb.bitmapData.rect, new Point(space, space), _gfilter);
//				_focusLayer.bitmapData.applyFilter(_focusLayer.bitmapData, _focusLayer.bitmapData.rect, new Point(), _bfilter);
				_focusLayer.x = p.x - space;
				_focusLayer.y = p.y - space;
				_focusLayer.smoothing = true;
			}
			
			//editor.dragRect.visible = (editor.dragRect.link != this) && (editor.dragRect.link != null);
		}
		
		protected function doHoleUnFocus(): void {
			updateHoleFocus(false);
			_holeFocus = -1;
		}
		
		protected function createHoles(a_holes: Array): void {
			_holes 		= a_holes;
			_curHole 	= -1;
			for (var i: int=0; i<_holes.length; i++) addHole(i);
		}
		
		public function set curHole(a_curHole: int): void {
			if (_curHole != a_curHole) {
				_curHole = a_curHole;
				workspace.dispatchEvent(new ObjectEvent(c_events.CHANGECURHOLE, This));
			}
		}
		
		public function get curHole(): int {
			return _curHole;
		}
		
		protected function addHole(index: int): void {
			var holeInfo: Object = _holes[index];
			var _hole: uif_bitmap = new c_hole(holeInfo.spot);
			_hole.visible = false;
			//_hole.alpha = 0.7;
			parent.addChild(_hole);
			_curHole = index;
			_holes[_curHole].mask = _hole;
			updateHoleTransform(index);
			
			//new uif_ecomponent(this, holeInfo.bounds.x, holeInfo.bounds.y, holeInfo.bounds.width, holeInfo.bounds.height, 'modalGurtain'); 
		}
		
		protected function updateHoleTransform(index: int): void {
			var holeInfo: Object = _holes[index];
			var mat: Matrix = new Matrix(1, 0, 0, 1, holeInfo.bounds.x, holeInfo.bounds.y);
			mat.concat(transform.matrix);
			_holes[index].mask.transform.matrix = mat;
		}
		
		override protected function updateRelativeMatrix(): void {
			super.updateRelativeMatrix();
			if (_holes) for (var i: int=0; i<_holes.length; i++) updateHoleTransform(i);
		}
		
/*		
		public function insertInHole(a_obj: c_baseElement): void {
			if (_curHole > -1) {
				var hole	: Object = _holes[_curHole];
				
				if (hole.image) {
					hole.image.owner = null;
					hole.image.remove();
				}
				
//				var inRect	: Rectangle = uif_util.EnterHere(hole.bounds, size, false);
				var scale	: Number = Math.max(hole.bounds.width/a_obj.width, hole.bounds.height/a_obj.height);
				var mat		: Matrix = new Matrix();
				var oc		: Point  = new Point(a_obj.width / 2, a_obj.height / 2);
				
				mat.translate(-oc.x, -oc.y);
				mat.scale(scale, scale);
				mat.translate(hole.bounds.x + hole.bounds.width / 2, 
								hole.bounds.y + hole.bounds.height / 2);
				mat.concat(matrix);
				
				a_obj.matrix = mat;
				
				hole.mask.visible = true;
				a_obj.mask = hole.mask;
				hole.image = a_obj;
				parent.swapChildren(this, a_obj);
				a_obj.owner = this;
			}
		}
*/		
		
		override protected function setIndex(a_index:int):void {
			var index: int = a_index;
			for (var i: int=0; i<_holes.length; i++) {
				if (_holes[i].image) {
					_holes[i].image.index = index;
					if (a_index == 0) index++;
				}
			}	
			super.setIndex(index);
		}
		
		override public function setParent(a_parent:c_pcomponent, a_index:int=-1):void {
			if (_holes)
				for (var i: int=0; i<_holes.length; i++) {
					a_parent.addChild(_holes[i].mask);
					if (_holes[i].image) a_parent.addChild(_holes[i].image);
				}
			super.setParent(a_parent);
			if (a_index > -1) index = a_index;
		}

		override public function remove():void {
			for (var i: int=0; i<_holes.length; i++) {
				if (_holes[i].mask.parent) _holes[i].mask.parent.removeChild(_holes[i].mask);
				if (_holes[i].image) _holes[i].image.remove();
			}
			super.remove();
		}
		
		override public function dispose():void {
			super.dispose();
			for (var i: int=0; i<_holes.length; i++) {
				_holes[i].mask.dispose();
				if (_holes[i].image) _holes[i].image.dispose();
			}
			if (_focusLayer.bitmapData) _focusLayer.bitmapData.dispose();
		}
		
		override public function executeMySelect(): void {
//			if (holeFocus > -1) curHole = holeFocus
			if (holeFocus > -1) {
				executeCommand(new c_holeSelectCommand(this, holeFocus));
				if (holeFocusImage) executeCommand(new c_linkCommand(editor.dragRect, holeFocusImage));
				else super.executeMySelect();
			} else super.executeMySelect();// executeCommand(new c_linkCommand(editor.dragRect, this));
		}		
		
		protected function doRectDown(e: MouseEvent): void {
			if (editor && (editor.dragRect.link == this)) {
				if (holeFocus > -1) 
					executeCommand(new c_holeSelectCommand(this, holeFocus));
				if (holeFocusImage) 
					executeCommand(new c_linkCommand(editor.dragRect, holeFocusImage));
			}
		}
	}
}